import java.awt.Point;
import java.util.ArrayList;

import pulpcore.animation.Easing;
import pulpcore.animation.Int;
import pulpcore.image.BlendMode;
import pulpcore.image.Colors;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.image.filter.*;
import pulpcore.image.filter.Blur;
import pulpcore.image.filter.ColorOverlay;
import pulpcore.image.filter.Filter;
import pulpcore.image.filter.Glow;
import pulpcore.image.filter.HSBAdjust;
import pulpcore.Input;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.Group;
import pulpcore.sprite.ImageSprite;
import pulpcore.sprite.Sprite;
import pulpcore.Stage;
import static pulpcore.image.Colors.*;

public class Test extends Scene2D {
    
    String[] tiles = {
        "Water Block.png",
        "Stone Block.png",
        "Grass Block.png",
        "Dirt Block.png",
    };
    
    String[] map = {
        "GGGGGGGGGG",
        "GGGGGGGGGG",
        "GGGDSSDGGG",
        "GGGDSSDGGG",
        "GGGGGGGGGG",
        "GGGGGGGGGG",
    };
    String[] map2 = {
         "W"
        };
    ImageSprite[][] grid = new ImageSprite[map[0].length()][map.length];
    Tile[][] tilegrid = new Tile[map[0].length()][map.length];
    
    TileMapSprite tileMap;
    ImageSprite cursor;
    Group mapSprites;

    Character selectedchar;
    
   
    //Character selected = new Character;
    ImageSprite warrior = new ImageSprite ("warrior1.png", Stage.getWidth()/2, 0);
    ImageSprite  tank = new ImageSprite ("tank1.png", Stage.getWidth()/2, 100);
    ImageSprite  berserk = new ImageSprite ("berserker1.png", Stage.getWidth()/2, 100);
    //Character selected = new Character;

    Weapon IronSword = new Weapon("Iron Sword", "sword");
    Role badass = new Role("badass", IronSword);
    Character Joel = new Character("Joel", berserk, badass, new Point(0,0) ,100, 100, 100, 100, 5, 100, 100, 100, 100);
    Character Evan = new Character("Evan", tank, badass, new Point(4,4) , 1, 1, 1, 1, 2, 1, 1, 1, 1);

    ArrayList<Character> team = new ArrayList<Character>();
    @Override
    public void load() {
        // Add the background (sky-blue)
        add(new FilledSprite(rgb(100, 200, 255)));
        
        team.add(Joel);
        team.add(Evan);
        
        // Add the tileset
        tileMap = createTileMapSprite(tiles, map2, 100, 80);
        
        add(tileMap);
        
        mapSprites = new Group();
        
        for (int i = 0; i < map.length; i++){
        	for (int j = 0; j < map[0].length(); j++)
        	{
        		if (map[i].charAt(j) == 'G')
        			grid[j][i] = new ImageSprite("Grass Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'S')
            		grid[j][i] = new ImageSprite("Stone Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'W')
            		grid[j][i] = new ImageSprite("Water Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'D')
            		grid[j][i] = new ImageSprite("Dirt Block.png",j*100,i*80);
        		mapSprites.add(grid[j][i]);
        		tilegrid[j][i] = new Tile(new Point(j,i), grid[j][i]);
        	}
        }        
        
        mapSprites.add(berserk);
        mapSprites.add(tank);
        
      
        
        grid[1][1].setFilter(new Glow(.1));
        
        for (Character i : team)
        {
        	i.getSprite().moveTo(i.getPositionX()*100,i.getPositionY()*80-80, 100);
        	tilegrid[i.getPositionX()][i.getPositionY()].setCharacter(i);

        }
        
        // Add the cursor

        
        mapSprites.x.bindTo(tileMap.viewX);
        mapSprites.y.bindTo(tileMap.viewY);
        add(mapSprites);
        
        setCursor(Input.CURSOR_OFF);
        cursor = new ImageSprite("cursor.png", 0, 0);
        cursor.setBlendMode(BlendMode.Add());
        cursor.bindLocationTo(tileMap);
        add(cursor);
        
    }
    
    @Override
    public void update(int elapsedTime) {
    	
        cursor.setLocation(Input.getMouseX(), Input.getMouseY());
        if (selectedchar != null){
	        for (int i = selectedchar.getPositionY()-selectedchar.getMove(); i <= selectedchar.getPositionY()+selectedchar.getMove(); i++){
	        	for (int j = selectedchar.getPositionX()-selectedchar.getMove(); j <= selectedchar.getPositionX()+selectedchar.getMove(); j++)
	        	{
	        		if (i > -1 && i < map.length && j > -1 && j < map[0].length())
	        		{
	        			if (tilegrid[j][i].getCharacter() == null)
	        			{
	        				if (Math.abs(selectedchar.getPositionY()-i)+Math.abs(selectedchar.getPositionX()-j) < selectedchar.getMove())
	        				{
	        					tilegrid[j][i].setSpecial();
	        				}
	        			}
	        			
	        		}
	        	}
	        }
        }
        else
        {
            for (int i = 0; i < map.length; i++){
            	for (int j = 0; j < map[0].length(); j++)
            	{
	        		tilegrid[j][i].unSpecial();
	        	}
        	}
        }
        
        //CLICKING
        if (Input.isMousePressed())
        {
            int x = Input.getMousePressX();
            int y = Input.getMousePressY();
            int goalX = tileMap.viewX.get() - (x - Stage.getWidth() /2)/2;
            int goalY = tileMap.viewY.get() - (y - Stage.getHeight() /2)/2;
            if (x < 100 || x > Stage.getWidth() - 100)
            {
            tileMap.viewX.animateTo(goalX, 500, Easing.REGULAR_OUT);
            }
            if (y < 100 || y > Stage.getHeight() - 100)
            {
            tileMap.viewY.animateTo(goalY, 500, Easing.REGULAR_OUT);
            }
            
            //move character
            //if a character is selected
            if (selectedchar != null)
            {
            	//then look through the grid
                for (int i = 0; i < map.length; i++){
                	for (int j = 0; j < map[0].length(); j++)
                	{
                		//if its still selected
                		if (selectedchar != null)
                        {
                			//see if a space clicked on
		                	if (tilegrid[j][i].getSprite().isMousePressed()){
		                		//then see if its a space you can move to
		                		if (tilegrid[j][i].getSpecial())
		                    	{
		                        	tilegrid[selectedchar.getPositionX()][selectedchar.getPositionY()].setCharacter(null);
			                		selectedchar.setPosition(j,i);
			                		tilegrid[j][i].setCharacter(selectedchar);
			                		
			                		selectedchar.getSprite().moveTo(j*100, i*80-80, 100);
			                		selectedchar = null;
		                    	}
			                }
                        }
                	}
                }
            }
        }
        //findglowspaces
 
        
        
       
       Glow gl = new Glow(.1);
	   if (selectedchar != null)
	   {
	       selectedchar.getSprite().setFilter(gl);
	   }   
	   for (int i = 0; i < map.length; i++){
	       for (int j = 0; j < map[0].length(); j++)
	       {
	        	if (tilegrid[j][i].getSpecial())
	        	{
	        		tilegrid[j][i].getSprite().setFilter(new HSBAdjust(50, -50, -50));
	        	}
	        	else
	        	{
	        		tilegrid[j][i].getSprite().setFilter(null);
	        	}
	        }
	   	}
        
        for (Character i : team)
        {
        	if (i.selected() != null)
        	selectedchar = i;

        }
   
        
        // When scrolling, disable dirty rectangles and hide the cursor
        setDirtyRectanglesEnabled(!tileMap.isScrolling());
        cursor.visible.set(Input.isMouseInside() && !tileMap.isScrolling());
      }
        
    
    
    TileMapSprite createTileMapSprite(String[] tiles, String[] map, int tileWidth, int tileHeight) {
        // Load tile images
        CoreImage[] tileImages = new CoreImage[tiles.length];
        for (int i = 0; i < tiles.length; i++) {
            tileImages[i] = CoreImage.load(tiles[i]);
        }
        
        // Create the tile map
        int mapWidth = map[0].length();
        int mapHeight = map.length;
        CoreImage[][] tileMapImages = new CoreImage[mapWidth][mapHeight];
        for (int i = 0; i < mapWidth; i++) {
            for (int j = 0; j < mapHeight; j++) {
                
                // Convert the map char to the first letter of the tile name
                // i.e., 'W' = "Water Block.png"
                char ch = map[j].charAt(i);
                int index = 0;
                for (int k = 0; k < tiles.length; k++) {
                    if (tiles[k].charAt(0) == ch) {
                        index = k;
                        break;
                    }
                }
                tileMapImages[i][j] = tileImages[index];
            }
        }
        return new TileMapSprite(tileMapImages, tileWidth, tileHeight);
    }
    
    /**
        A simple tile map.
        Limitation: the maximum width and height of a TileMap 
        (i.e. tileWidth*numTilesAcross and tileHeight*numTilesDown) should be less than 32768.
    */

    static class TileMapSprite extends Sprite{
        
        private CoreImage[][] tileMap;
        private int tileWidth;
        private int tileHeight;
        private int numTilesAcross;
        private int numTilesDown;
        
       
        public final Int viewX = new Int(this);
        public final Int viewY = new Int(this);
        
        public TileMapSprite(CoreImage[][] tileMap, int tileWidth, int tileHeight) {
            super(0, 0, Stage.getWidth(), Stage.getHeight());
            this.tileMap = tileMap;
            this.tileWidth = tileWidth;
            this.tileHeight = tileHeight;
            numTilesAcross = tileMap.length;
            numTilesDown = tileMap[0].length;
        }
        
        public CoreImage getCoreImage(int x, int y){
        	return tileMap[x][y];
        }
        public int getMapWidth() {
            return tileWidth * numTilesAcross;
        }
        
        public int getMapHeight() {
            return tileHeight * numTilesDown;
        }
        
        public boolean isScrolling() {
            return viewX.isAnimating() || viewY.isAnimating();
        }
        
        @Override 
        public void update(int elapsedTime) {
        	
            super.update(elapsedTime);
            viewX.update(elapsedTime);
            viewY.update(elapsedTime);
           
           
            
        }
        
        public void flip(int x, int y){
        	CoreImage evan = getCoreImage(x, y);
            evan.flip();
        }
        
        @Override
        protected void drawSprite(CoreGraphics g) {
            int y = viewY.get();
            for (int j = 0; j < numTilesDown; j++) {
                int x = viewX.get();
                for (int i = 0; i < numTilesAcross; i++) {
                    g.drawImage(tileMap[i][j], x, y);
                    x += tileWidth;
                }
                y += tileHeight;
            }
        }
    }
}